package com.jt.resource.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * 资源服务器的配置，在这个对象中重点要实现：
 * 1)JWT令牌解析的配置(客户端带着令牌访问资源时，要对令牌进行解析)
 * 2)启动资源访问的授权配置(不是所有登陆用户可以访问所有资源)
 */
@Configuration
@EnableResourceServer //此注解会启动资源服务器的默认配置
@EnableGlobalMethodSecurity(prePostEnabled = true) //执行方法之前启动权限检查
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;
    /**
     * token服务配置
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore);

    }
    /**
     * 路由安全认证配置
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
       // http.exceptionHandling()
                //不携带令牌去访问,会提示请先登录(认证)
                //.authenticationEntryPoint(authenticationEntryPoint())
                //.accessDeniedHandler(accessDeniedHandler());
        http.authorizeRequests().anyRequest().permitAll();

    }
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, exception) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("state", HttpServletResponse.SC_UNAUTHORIZED);//SC_FORBIDDEN的值是403
            map.put("message", "请先登陆");
            //1设置响应数据的编码
            response.setCharacterEncoding("utf-8");
            //2告诉浏览器响应数据的内容类型以及编码
            response.setContentType("application/json;charset=utf-8");
            //3获取输出流对象
            PrintWriter out=response.getWriter();
            //4 输出数据
            String result=
                    new ObjectMapper().writeValueAsString(map);
            out.println(result);
            out.flush();
        };
    }
    //没有权限时执行此处理器方法
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, e) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("state", HttpServletResponse.SC_FORBIDDEN);//SC_FORBIDDEN的值是403
            map.put("message", "没有访问权限,请联系管理员");
            //1设置响应数据的编码
            response.setCharacterEncoding("utf-8");
            //2告诉浏览器响应数据的内容类型以及编码
            response.setContentType("application/json;charset=utf-8");
            //3获取输出流对象
            PrintWriter out=response.getWriter();
            //4 输出数据
            String result=
                    new ObjectMapper().writeValueAsString(map);
            out.println(result);
            out.flush();
        };
    }
}
